/**
 *  author:		nbsp - http://www.xujiantao.com
 *	version:	NbspAutoComplete1.0 - 2012-09-22
 */
(function($) {
	$.fn.NbspAutoComplete = function(options){
		var defaults = {
			location       : "",  				   // if file is xml && datatype is xml  | if file is asp php... && dataype is json 
			liheight       : "22px",               // <li> height
			selectcount    : "all",  	           // number or all or scrollbar
			scrollbarcount : 4,                    // scrollbar count
			datatype       : "json"                // json or xml
		}; 
		
		$(this).attr("autocomplete","off");
		$(this).parent().append("<div class='nbspauto'><ul></ul></div>");
		$(this).parent().find(".nbspauto").css("width",$(this).outerWidth(true)-2);
		
		var options = $.extend(defaults, options);
		var _obj = $(this);
		var _num= 0;
		var _selectnum;
		var _hovers;
		var _thisTEXT;
		var _curr = $(this).parent().find(".nbspauto");
		var _limerge;
		var _lastindex;
		
		//Custom events: select hidden
		$(this).parent().find(".nbspauto").bind("scolse",function(){
			$(this).hide().find("ul").html("");
		});
		
        //Input character after the treatment
		_obj.keyup(function(event){
			var keyCode = event.which;
			var _startDOM;
			if(keyCode == 38 || keyCode == 40 || keyCode == 13){
				keyups(keyCode);
			}else{
				$.get(options.location,{input:_obj.val()},function(datas){
					//if xml data or json data
					options.datatype == "xml" ? _startDOM = $(datas).find(_obj.val()).find("data") : "";
					options.datatype == "json" ? _startDOM = $(datas) : "";
					eachs(_startDOM);
					currshow();
				},options.datatype);
			}
		});
		
		//Ergodic automatic prompt results sets add dom
		function eachs(_startDOM){
			_limerge = "";
			_startDOM.each(function(i){
				if(this.value != ""){
					options.datatype == "xml" ? _thisTEXT = $(this).text() : "";
					options.datatype == "json" ? _thisTEXT = this.value : "";
					if((options.selectcount == "all" || options.selectcount == "scrollbar") ||
					(options.selectcount != "all") && (i < options.selectcount)){
						_limerge += "<li>"+_thisTEXT+"</li>";
						_selectnum = i;
					}
				}
			});
			if(_curr.find("ul").find(".clicks").text() != _obj.val()){
				_curr.find("ul").html(_limerge);
			}
			_lastindex = _curr.find("li").last().index()+1;
			//The result set rolling style
			if(options.selectcount == "scrollbar"){
				var scrollheight;
				if(_lastindex < options.scrollbarcount){
					scrollheight = _lastindex*parseInt(options.liheight)
				}else{
					scrollheight = options.scrollbarcount*parseInt(options.liheight)
				}
				_curr.css({"height":scrollheight,"overflow":"auto"});
			}
		}
		
		//An automated display and mouse after style
		function currshow(){
			if(_limerge == ""){
				_curr.trigger("scolse");
			}else{
				_curr.show().end().find("li").css({
					"height":options.liheight,
					"line-height":options.liheight
				});
				_curr.find("li").hover(function(){
					if(_hovers != 1){
						_num = $(this).index()+1;
					    _curr.find("li").removeClass("clicks");
						$(this).addClass("clicks");
					}
				},function(){
					_hovers = 0;
				});
			}
		}
		
		//Keyboard up down enter key operation
		function keyups(k){
			switch(k){
				case 40:
					_hovers = 1;
					_num < _selectnum+1 ? _num = _num+1 : _num = 1;
					var _thisli = _curr.find("li:eq("+parseInt(_num-1)+")");
					_curr.find("li").removeClass("clicks");
					_thisli.addClass("clicks");
					_obj.val(_thisli.text());
					
					if(options.selectcount == "scrollbar"){
						_num > options.scrollbarcount 
						? _curr.scrollTop(_curr.scrollTop() + parseInt(options.liheight))
						: _curr.scrollTop(0);
					}
					break   
				case 38:
					_num <= 1 ? _num = _selectnum+1 : _num = _num-1;
					var _thisli = _curr.find("ul").find("li:eq("+parseInt(_num-1)+")");
					_curr.find("li").removeClass("clicks");
					_thisli.addClass("clicks");
					_obj.val(_thisli.text());
					
					if(options.selectcount == "scrollbar"){
						if((_num < _lastindex) && ((_lastindex-_num+1) > options.scrollbarcount)){
							_curr.scrollTop(_curr.scrollTop() - parseInt(options.liheight));
						}else{
							_curr.scrollTop(_lastindex * parseInt(options.liheight));
						}
					}
					break
				case 13:
					_curr.trigger("scolse").end().parentsUntil("form").submit();
					break
			}
		}
		
		//If you don't click on li and leave input box focus
		_obj.blur(function(){
			_obj.parent().find(".nbspauto li").click(function(){
				_obj.val($(this).text());
			});
			$(document).not(_obj).click(function(){
				_obj.parent().find(".nbspauto").trigger("scolse");
			});
		});	
	}
})(jQuery);